// License Notification
//======================================================
// Copyright (c) 2010 Channel Intelligence Inc.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// ======================================================




using CIP4.Item;
using CIP4.Common;

namespace CIP4.Simple
{

    //[CIP4Item(AddAllProperties=true)]
    public class CIP4ReferenceType<TTargetType> : CIP4ReferenceBaseType where TTargetType : class
    {


        [CIP4Property(DontSerialize = true)]
        public override string TargetCollection
        {
            get
            {
                CIP4ItemAttribute att = CIP4ItemAttribute.GetAttribute(typeof(TTargetType));
                return att.Collection;
            }
        }

        [CIP4Property(DontSerialize = true)]
        public override bool HasValue
        {
            get { return !string.IsNullOrEmpty(TargetExternalID)? true : Target != null; }
        }

        private TTargetType _target;
        [CIP4Property(DontSerialize=true)]
        public TTargetType Target 
        {
            get
            {
                if (StrongWrapperBase.Wrappers.ContainsKey(StrongWrapperBase.GetWrapperLabel<TTargetType>(TargetCollection)))
                {
                    StrongWrapper<TTargetType> wrapper = (StrongWrapper<TTargetType>)StrongWrapperBase.Wrappers[StrongWrapperBase.GetWrapperLabel<TTargetType>(TargetCollection)];
                    if (_target != null && wrapper.GetSerializer(SerializerKindEnum.CIP4Xml).GetExternalID(_target).ToString() == TargetExternalID)
                        return _target;
                    return _target = wrapper.GetViaExternalID(ExternalIDType.ExternalIDFromEscapedString(TargetExternalID), Globals.DefaultLogger);
                }
                return default(TTargetType);
            }
            set
            {
                if (StrongWrapperBase.Wrappers.ContainsKey(StrongWrapperBase.GetWrapperLabel<TTargetType>(TargetCollection)))
                {
                    StrongWrapper<TTargetType> wrapper = (StrongWrapper<TTargetType>)StrongWrapperBase.Wrappers[StrongWrapperBase.GetWrapperLabel<TTargetType>(TargetCollection)];
                    TargetExternalID = wrapper.GetSerializer(SerializerKindEnum.CIP4Xml).GetExternalID(value).ToString();
                    _target = value;
                }
                else
                    Globals.LoggerWrapper(MajorEnum.Error, MinorEnum.SerializationError,
                        "No wrapper has been allocated for the target collection {0} so the reference cannot be set", new object[] { TargetCollection }, Globals.DefaultLogger);
            }
        }
    }
}
